<?php
/* SVN FILE: $Id: assigned_assessments_controller.php 24 2009-10-01 01:35:53Z kenreily@gmail.com $ */
/**
 * Short description for file.
 *
 * Long description for file
 *
 * PHP versions 4 and 5
 *
 * Recenseo: Online submission and reviewing for education
 * Copyright 2008-2009, Ken Reily
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * $Date: 2009-10-01 01:35:53 +0000 (Thu, 01 Oct 2009) $
 * $Revision: 24 $
 * $Author: kenreily@gmail.com $
 * $HeadURL: http://recenseo.googlecode.com/svn/trunk/app/controllers/assigned_assessments_controller.php $
 */
class AssignedAssessmentsController extends AppController
{
  var $name = 'AssignedAssessments';
  var $helpers = array('Time');
  var $components = array('Email');
  var $scaffold = 'admin';

  // This method is used to generate review pairings for a specific
  // assignment.
  function admin_generate($assignment_id)
  {
    $assignment = $this->AssignedAssessment->Assignment->findById($assignment_id);

    $this->set('assignment',$assignment);
    $this->pageTitle = "Assigning Assessments for {$assignment['Assignment']['name']}";

    $asmt_count = $this->AssignedAssessment->find('count',
						  array('conditions' => array('Assignment.id' => $assignment_id)));
    $this->set('asmtCount',$asmt_count);

    // TODO: Limit this to users in the TA role.
    $reviewers = $this->AssignedAssessment->Reviewer->find('list',array('order' => 'Reviewer.username'));
    $this->set('reviewerUsers',$reviewers);

    if (!empty($this->data))
    {
      $course = $this->AssignedAssessment->Reviewer->Course->findById($assignment['Assignment']['course_id']);

      // Parallel arrays: one for reviewers and one for reviewees.
      $reviewer_list = array();
      $reviewee_list = array();

      for ($i = 0; $i < 3; $i++)
      {	
	foreach ($course['User'] as $user)
	{
	  if ($user['reviewer'] == 1)
	  {
	    $reviewer_list[] = $user['id'];
	  }

	  if ($user['reviewee'] == 1)
	  {
	    $reviewee_list[] = $user['id'];
	  }
	}
      }

      // This loop uses brute force to generate candidate pairings and check them 
      // against two constraints:
      // 1. Students may not review themselves, and 
      // 2. Students may not review another student more than once.
      $done = false;
      $attempt = 0;
      
      do
      {
	// We'll keep track of how many times we had to do this for posterity
	$attempt++;

	// Shuffle one of the lists to randomly match reviewers and authors
	shuffle($reviewee_list);
	shuffle($reviewer_list);

	// This array will help keep track of duplicate pairs.
	$dup_arr = array();

	// Condition 1: No student can review themselves. Loop through
	// the arrays looking for cases where reviewee and reviewer are
	// the same.
	$self_review = false;

	for ($i = 0; $i < count($reviewee_list); $i++)
	{
	  if ($reviewer_list[$i] == $reviewee_list[$i])
	  {
	    // Try again!
	    $self_review = true;
	    break;
	  }

	  $dup_arr[] = $reviewee_list[$i] . $reviewer_list[$i];
	}

	if ($self_review)
	{
	  continue;
	}
	    
	// Condition 2: No student can review the same student 
	// more than once for a single assignment. If the count on
	// our dup_arr matches either of the individual lists, we have
	// no duplicates.
	$dups = false;

	foreach (array_count_values($dup_arr) as $count)
	{
	  if ($count > 1)
	  {
	    $dups = true;
	    break;
	  }
	}

	if (!$dups)
	{
	  $done = true;
	}

      } while (!$done);

      // Now, save the results. Start by deleting any current assignments.
      $params = array('Assignment.id' => $assignment_id);
      $this->AssignedAssessment->deleteAll($params);

      $savedata['AssignedAssessment'] = array();


      // Generate assigned assessments for TA
      foreach ($course['User'] as $reviewee)
      {
	$record['assignment_id'] = $assignment_id;
	$record['reviewer_user_id'] = $this->data['AssignedAssessment']['reviewer_user_id'];
	$record['reviewee_user_id'] = $reviewee['id'];
	$savedata['AssignedAssessment'][] = $record;
      }

      for ($i = 0; $i < count($reviewer_list); $i++)
      {
	$record['assignment_id'] = $assignment_id;
	$record['reviewer_user_id'] = $reviewer_list[$i];
	$record['reviewee_user_id'] = $reviewee_list[$i];
	$savedata['AssignedAssessment'][] = $record;
      }

      $this->AssignedAssessment->saveAll($savedata['AssignedAssessment'],
					 array('atomic' => true));

      $this->flash('Assessment assignments generated!',"/admin/assigned_assessments/index/");

    }
  }
}
?>